﻿#region license

// Copyright (c) 2021, andreakarasho
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
//    must display the following acknowledgement:
//    This product includes software developed by andreakarasho - https://github.com/andreakarasho
// 4. Neither the name of the copyright holder nor the
//    names of its contributors may be used to endorse or promote products
//    derived from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#endregion

namespace ClassicUO.IO.Audio.MP3Sharp.Decoding.Decoders.LayerII
{
    /// <summary>
    ///     Class for layer II subbands in single channel mode.
    /// </summary>
    internal class SubbandLayer2 : ASubband
    {
        // this table contains 3 requantized samples for each legal codeword
        // when grouped in 5 bits, i.e. 3 quantization steps per sample
        public static readonly float[] grouping_5bits =
        {
            -2.0f / 3.0f, -2.0f / 3.0f, -2.0f / 3.0f, 0.0f, -2.0f / 3.0f, -2.0f / 3.0f, 2.0f / 3.0f, -2.0f / 3.0f,
            -2.0f / 3.0f,
            -2.0f / 3.0f, 0.0f, -2.0f / 3.0f, 0.0f, 0.0f, -2.0f / 3.0f, 2.0f / 3.0f, 0.0f, -2.0f / 3.0f, -2.0f / 3.0f,
            2.0f / 3.0f,
            -2.0f / 3.0f, 0.0f, 2.0f / 3.0f, -2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f, -2.0f / 3.0f, -2.0f / 3.0f,
            -2.0f / 3.0f, 0.0f,
            0.0f, -2.0f / 3.0f, 0.0f, 2.0f / 3.0f, -2.0f / 3.0f, 0.0f, -2.0f / 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
            2.0f / 3.0f,
            0.0f, 0.0f, -2.0f / 3.0f, 2.0f / 3.0f, 0.0f, 0.0f, 2.0f / 3.0f, 0.0f, 2.0f / 3.0f, 2.0f / 3.0f, 0.0f,
            -2.0f / 3.0f,
            -2.0f / 3.0f, 2.0f / 3.0f, 0.0f, -2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f, -2.0f / 3.0f, 2.0f / 3.0f,
            -2.0f / 3.0f, 0.0f,
            2.0f / 3.0f, 0.0f, 0.0f, 2.0f / 3.0f, 2.0f / 3.0f, 0.0f, 2.0f / 3.0f, -2.0f / 3.0f, 2.0f / 3.0f,
            2.0f / 3.0f, 0.0f,
            2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f
        };

        // this table contains 3 requantized samples for each legal codeword
        // when grouped in 7 bits, i.e. 5 quantizationsteps per sample
        public static readonly float[] grouping_7bits =
        {
            -0.8f, -0.8f, -0.8f, -0.4f, -0.8f, -0.8f, 0.0f, -0.8f, -0.8f, 0.4f, -0.8f, -0.8f, 0.8f, -0.8f, -0.8f,
            -0.8f, -0.4f, -0.8f, -0.4f, -0.4f, -0.8f, 0.0f, -0.4f, -0.8f, 0.4f, -0.4f, -0.8f, 0.8f, -0.4f, -0.8f,
            -0.8f, 0.0f, -0.8f, -0.4f, 0.0f, -0.8f, 0.0f, 0.0f, -0.8f, 0.4f, 0.0f, -0.8f, 0.8f, 0.0f, -0.8f, -0.8f,
            0.4f, -0.8f, -0.4f, 0.4f, -0.8f, 0.0f, 0.4f, -0.8f, 0.4f, 0.4f, -0.8f, 0.8f, 0.4f, -0.8f, -0.8f, 0.8f,
            -0.8f, -0.4f, 0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.4f, 0.8f, -0.8f, 0.8f, 0.8f, -0.8f, -0.8f, -0.8f, -0.4f,
            -0.4f, -0.8f, -0.4f, 0.0f, -0.8f, -0.4f, 0.4f, -0.8f, -0.4f, 0.8f, -0.8f, -0.4f, -0.8f, -0.4f, -0.4f,
            -0.4f, -0.4f, -0.4f, 0.0f, -0.4f, -0.4f, 0.4f, -0.4f, -0.4f, 0.8f, -0.4f, -0.4f, -0.8f, 0.0f, -0.4f,
            -0.4f, 0.0f, -0.4f, 0.0f, 0.0f, -0.4f, 0.4f, 0.0f, -0.4f, 0.8f, 0.0f, -0.4f, -0.8f, 0.4f, -0.4f, -0.4f,
            0.4f, -0.4f, 0.0f, 0.4f, -0.4f, 0.4f, 0.4f, -0.4f, 0.8f, 0.4f, -0.4f, -0.8f, 0.8f, -0.4f, -0.4f, 0.8f,
            -0.4f, 0.0f, 0.8f, -0.4f, 0.4f, 0.8f, -0.4f, 0.8f, 0.8f, -0.4f, -0.8f, -0.8f, 0.0f, -0.4f, -0.8f, 0.0f,
            0.0f, -0.8f, 0.0f, 0.4f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f, -0.8f, -0.4f, 0.0f, -0.4f, -0.4f, 0.0f, 0.0f,
            -0.4f, 0.0f, 0.4f, -0.4f, 0.0f, 0.8f, -0.4f, 0.0f, -0.8f, 0.0f, 0.0f, -0.4f, 0.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 0.4f, 0.0f, 0.0f, 0.8f, 0.0f, 0.0f, -0.8f, 0.4f, 0.0f, -0.4f, 0.4f, 0.0f, 0.0f, 0.4f, 0.0f, 0.4f,
            0.4f, 0.0f, 0.8f, 0.4f, 0.0f, -0.8f, 0.8f, 0.0f, -0.4f, 0.8f, 0.0f, 0.0f, 0.8f, 0.0f, 0.4f, 0.8f, 0.0f,
            0.8f, 0.8f, 0.0f, -0.8f, -0.8f, 0.4f, -0.4f, -0.8f, 0.4f, 0.0f, -0.8f, 0.4f, 0.4f, -0.8f, 0.4f, 0.8f,
            -0.8f, 0.4f, -0.8f, -0.4f, 0.4f, -0.4f, -0.4f, 0.4f, 0.0f, -0.4f, 0.4f, 0.4f, -0.4f, 0.4f, 0.8f, -0.4f,
            0.4f, -0.8f, 0.0f, 0.4f, -0.4f, 0.0f, 0.4f, 0.0f, 0.0f, 0.4f, 0.4f, 0.0f, 0.4f, 0.8f, 0.0f, 0.4f, -0.8f,
            0.4f, 0.4f, -0.4f, 0.4f, 0.4f, 0.0f, 0.4f, 0.4f, 0.4f, 0.4f, 0.4f, 0.8f, 0.4f, 0.4f,
            -0.8f, 0.8f, 0.4f, -0.4f, 0.8f, 0.4f, 0.0f, 0.8f, 0.4f, 0.4f, 0.8f, 0.4f, 0.8f, 0.8f, 0.4f, -0.8f, -0.8f,
            0.8f, -0.4f, -0.8f, 0.8f, 0.0f, -0.8f, 0.8f, 0.4f, -0.8f, 0.8f, 0.8f, -0.8f, 0.8f, -0.8f, -0.4f, 0.8f,
            -0.4f, -0.4f, 0.8f, 0.0f, -0.4f, 0.8f, 0.4f, -0.4f, 0.8f, 0.8f, -0.4f, 0.8f, -0.8f, 0.0f, 0.8f, -0.4f,
            0.0f, 0.8f, 0.0f, 0.0f, 0.8f, 0.4f, 0.0f, 0.8f, 0.8f, 0.0f, 0.8f, -0.8f, 0.4f, 0.8f, -0.4f, 0.4f, 0.8f,
            0.0f, 0.4f, 0.8f, 0.4f, 0.4f, 0.8f, 0.8f, 0.4f, 0.8f, -0.8f, 0.8f, 0.8f, -0.4f, 0.8f, 0.8f, 0.0f, 0.8f,
            0.8f, 0.4f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f
        };

        // this table contains 3 requantized samples for each legal codeword
        // when grouped in 10 bits, i.e. 9 quantizationsteps per sample
        public static readonly float[] grouping_10bits =
        {
            -8.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f,
            -8.0f / 9.0f,
            -8.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, 0.0f, -8.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f,
            -8.0f / 9.0f,
            -8.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f,
            -8.0f / 9.0f,
            -8.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f,
            -4.0f / 9.0f,
            -6.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 0.0f, -6.0f / 9.0f, -8.0f / 9.0f,
            2.0f / 9.0f,
            -6.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f,
            -8.0f / 9.0f, 8.0f / 9.0f,
            -6.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f,
            -8.0f / 9.0f,
            -4.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 0.0f, -4.0f / 9.0f,
            -8.0f / 9.0f,
            2.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f,
            -8.0f / 9.0f,
            8.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f,
            -2.0f / 9.0f,
            -8.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, 0.0f,
            -2.0f / 9.0f,
            -8.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f,
            -2.0f / 9.0f,
            -8.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, 0.0f, -8.0f / 9.0f, -6.0f / 9.0f, 0.0f,
            -8.0f / 9.0f, -4.0f / 9.0f, 0.0f, -8.0f / 9.0f, -2.0f / 9.0f, 0.0f, -8.0f / 9.0f, 0.0f, 0.0f, -8.0f / 9.0f,
            2.0f / 9.0f, 0.0f, -8.0f / 9.0f, 4.0f / 9.0f, 0.0f, -8.0f / 9.0f, 6.0f / 9.0f, 0.0f, -8.0f / 9.0f,
            8.0f / 9.0f, 0.0f,
            -8.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f,
            -4.0f / 9.0f, 2.0f / 9.0f,
            -8.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 0.0f, 2.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f,
            2.0f / 9.0f,
            -8.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f,
            2.0f / 9.0f,
            -8.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f,
            -4.0f / 9.0f, 4.0f / 9.0f,
            -8.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, 0.0f, 4.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f,
            4.0f / 9.0f,
            -8.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f,
            4.0f / 9.0f,
            -8.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f,
            -4.0f / 9.0f, 6.0f / 9.0f,
            -8.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 0.0f, 6.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f,
            6.0f / 9.0f,
            -8.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f,
            6.0f / 9.0f,
            -8.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f,
            -4.0f / 9.0f, 8.0f / 9.0f,
            -8.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 0.0f, 8.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f,
            8.0f / 9.0f,
            -8.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f,
            8.0f / 9.0f,
            -8.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f,
            -4.0f / 9.0f,
            -8.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 0.0f, -8.0f / 9.0f, -6.0f / 9.0f,
            2.0f / 9.0f,
            -8.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f,
            -6.0f / 9.0f, 8.0f / 9.0f,
            -8.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f,
            -6.0f / 9.0f,
            -4.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 0.0f, -6.0f / 9.0f,
            -6.0f / 9.0f,
            2.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f,
            4.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f,
            -6.0f / 9.0f,
            -8.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f,
            -4.0f / 9.0f,
            -6.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 0.0f, -4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f,
            -4.0f / 9.0f,
            -6.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f,
            -4.0f / 9.0f,
            -6.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f,
            -4.0f / 9.0f,
            -2.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 0.0f, -2.0f / 9.0f, -6.0f / 9.0f,
            2.0f / 9.0f,
            -2.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f,
            -6.0f / 9.0f, 8.0f / 9.0f,
            -2.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 0.0f, -6.0f / 9.0f, -6.0f / 9.0f, 0.0f, -6.0f / 9.0f,
            -4.0f / 9.0f, 0.0f,
            -6.0f / 9.0f, -2.0f / 9.0f, 0.0f, -6.0f / 9.0f, 0.0f, 0.0f, -6.0f / 9.0f, 2.0f / 9.0f, 0.0f, -6.0f / 9.0f,
            4.0f / 9.0f,
            0.0f, -6.0f / 9.0f, 6.0f / 9.0f, 0.0f, -6.0f / 9.0f, 8.0f / 9.0f, 0.0f, -6.0f / 9.0f, -8.0f / 9.0f,
            2.0f / 9.0f,
            -6.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f,
            -2.0f / 9.0f, 2.0f / 9.0f,
            -6.0f / 9.0f, 0.0f, 2.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f,
            2.0f / 9.0f,
            -6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f,
            4.0f / 9.0f,
            -6.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f,
            -2.0f / 9.0f, 4.0f / 9.0f,
            -6.0f / 9.0f, 0.0f, 4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f,
            4.0f / 9.0f,
            -6.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f,
            6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f,
            -2.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 0.0f, 6.0f / 9.0f, -6.0f / 9.0f,
            2.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f,
            -6.0f / 9.0f,
            8.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f,
            -6.0f / 9.0f,
            -4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 0.0f, 8.0f / 9.0f,
            -6.0f / 9.0f,
            2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f,
            -6.0f / 9.0f,
            8.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f,
            -8.0f / 9.0f, -4.0f / 9.0f,
            -4.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 0.0f, -8.0f / 9.0f,
            -4.0f / 9.0f,
            2.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f,
            -4.0f / 9.0f,
            8.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f,
            -6.0f / 9.0f,
            -4.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 0.0f,
            -6.0f / 9.0f,
            -4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f,
            -6.0f / 9.0f,
            -4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f,
            -6.0f / 9.0f,
            -4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f,
            -4.0f / 9.0f, 0.0f,
            -4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f,
            -4.0f / 9.0f, 6.0f / 9.0f,
            -4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f,
            -4.0f / 9.0f,
            -6.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f,
            -2.0f / 9.0f,
            -4.0f / 9.0f, 0.0f, -2.0f / 9.0f, -4.0f / 9.0f,
            2.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f,
            -4.0f / 9.0f,
            8.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 0.0f, -4.0f / 9.0f, -6.0f / 9.0f, 0.0f, -4.0f / 9.0f,
            -4.0f / 9.0f, 0.0f, -4.0f / 9.0f, -2.0f / 9.0f, 0.0f, -4.0f / 9.0f, 0.0f, 0.0f, -4.0f / 9.0f, 2.0f / 9.0f,
            0.0f,
            -4.0f / 9.0f, 4.0f / 9.0f, 0.0f, -4.0f / 9.0f, 6.0f / 9.0f, 0.0f, -4.0f / 9.0f, 8.0f / 9.0f, 0.0f,
            -4.0f / 9.0f,
            -8.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f,
            -4.0f / 9.0f,
            -2.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 0.0f, 2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f,
            -4.0f / 9.0f,
            4.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f,
            -4.0f / 9.0f,
            -8.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f,
            -4.0f / 9.0f,
            -2.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 0.0f, 4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f,
            -4.0f / 9.0f,
            4.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f,
            -4.0f / 9.0f,
            -8.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f,
            -4.0f / 9.0f,
            -2.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 0.0f, 6.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f,
            -4.0f / 9.0f,
            4.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f,
            -4.0f / 9.0f,
            -8.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f,
            -4.0f / 9.0f,
            -2.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 0.0f, 8.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f,
            -4.0f / 9.0f,
            4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f,
            -4.0f / 9.0f,
            -8.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f,
            -8.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f,
            -2.0f / 9.0f, 0.0f,
            -8.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f,
            -2.0f / 9.0f, 6.0f / 9.0f,
            -8.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f,
            -2.0f / 9.0f,
            -6.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f,
            -6.0f / 9.0f,
            -2.0f / 9.0f, 0.0f, -6.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f,
            -6.0f / 9.0f,
            -2.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f,
            -8.0f / 9.0f, -4.0f / 9.0f,
            -2.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f,
            -2.0f / 9.0f,
            -4.0f / 9.0f, -2.0f / 9.0f, 0.0f, -4.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f,
            4.0f / 9.0f,
            -4.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f,
            -2.0f / 9.0f, -8.0f / 9.0f,
            -2.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f,
            -2.0f / 9.0f,
            -2.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, 0.0f, -2.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f,
            -2.0f / 9.0f,
            4.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f,
            -2.0f / 9.0f,
            -8.0f / 9.0f, 0.0f, -2.0f / 9.0f, -6.0f / 9.0f, 0.0f, -2.0f / 9.0f, -4.0f / 9.0f, 0.0f, -2.0f / 9.0f,
            -2.0f / 9.0f,
            0.0f, -2.0f / 9.0f, 0.0f, 0.0f, -2.0f / 9.0f, 2.0f / 9.0f, 0.0f, -2.0f / 9.0f, 4.0f / 9.0f, 0.0f,
            -2.0f / 9.0f,
            6.0f / 9.0f, 0.0f, -2.0f / 9.0f, 8.0f / 9.0f, 0.0f, -2.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f,
            -6.0f / 9.0f,
            2.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f,
            0.0f,
            2.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f,
            -2.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f,
            2.0f / 9.0f,
            -2.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f,
            -4.0f / 9.0f, 4.0f / 9.0f,
            -2.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, 0.0f, 4.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f,
            4.0f / 9.0f,
            -2.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f,
            4.0f / 9.0f,
            -2.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f,
            -4.0f / 9.0f, 6.0f / 9.0f,
            -2.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 0.0f, 6.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f,
            6.0f / 9.0f,
            -2.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f,
            6.0f / 9.0f,
            -2.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f,
            -4.0f / 9.0f, 8.0f / 9.0f,
            -2.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 0.0f, 8.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f,
            8.0f / 9.0f,
            -2.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f,
            8.0f / 9.0f,
            -2.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, 0.0f, -6.0f / 9.0f, -8.0f / 9.0f, 0.0f, -4.0f / 9.0f,
            -8.0f / 9.0f, 0.0f,
            -2.0f / 9.0f, -8.0f / 9.0f, 0.0f, 0.0f, -8.0f / 9.0f, 0.0f, 2.0f / 9.0f, -8.0f / 9.0f, 0.0f, 4.0f / 9.0f,
            -8.0f / 9.0f,
            0.0f, 6.0f / 9.0f, -8.0f / 9.0f, 0.0f, 8.0f / 9.0f, -8.0f / 9.0f, 0.0f, -8.0f / 9.0f, -6.0f / 9.0f, 0.0f,
            -6.0f / 9.0f,
            -6.0f / 9.0f, 0.0f, -4.0f / 9.0f, -6.0f / 9.0f, 0.0f, -2.0f / 9.0f, -6.0f / 9.0f, 0.0f, 0.0f, -6.0f / 9.0f,
            0.0f,
            2.0f / 9.0f, -6.0f / 9.0f, 0.0f, 4.0f / 9.0f, -6.0f / 9.0f, 0.0f, 6.0f / 9.0f, -6.0f / 9.0f, 0.0f,
            8.0f / 9.0f,
            -6.0f / 9.0f, 0.0f, -8.0f / 9.0f, -4.0f / 9.0f, 0.0f, -6.0f / 9.0f, -4.0f / 9.0f, 0.0f, -4.0f / 9.0f,
            -4.0f / 9.0f,
            0.0f, -2.0f / 9.0f, -4.0f / 9.0f, 0.0f, 0.0f,
            -4.0f / 9.0f, 0.0f,
            2.0f / 9.0f, -4.0f / 9.0f, 0.0f, 4.0f / 9.0f, -4.0f / 9.0f, 0.0f, 6.0f / 9.0f, -4.0f / 9.0f, 0.0f,
            8.0f / 9.0f,
            -4.0f / 9.0f, 0.0f, -8.0f / 9.0f, -2.0f / 9.0f, 0.0f, -6.0f / 9.0f, -2.0f / 9.0f, 0.0f, -4.0f / 9.0f,
            -2.0f / 9.0f,
            0.0f, -2.0f / 9.0f, -2.0f / 9.0f, 0.0f, 0.0f, -2.0f / 9.0f, 0.0f, 2.0f / 9.0f, -2.0f / 9.0f, 0.0f,
            4.0f / 9.0f,
            -2.0f / 9.0f, 0.0f, 6.0f / 9.0f, -2.0f / 9.0f, 0.0f, 8.0f / 9.0f, -2.0f / 9.0f, 0.0f, -8.0f / 9.0f, 0.0f,
            0.0f,
            -6.0f / 9.0f, 0.0f, 0.0f, -4.0f / 9.0f, 0.0f, 0.0f, -2.0f / 9.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f / 9.0f,
            0.0f, 0.0f, 4.0f / 9.0f, 0.0f, 0.0f, 6.0f / 9.0f, 0.0f, 0.0f, 8.0f / 9.0f, 0.0f, 0.0f, -8.0f / 9.0f,
            2.0f / 9.0f,
            0.0f, -6.0f / 9.0f, 2.0f / 9.0f, 0.0f, -4.0f / 9.0f, 2.0f / 9.0f, 0.0f, -2.0f / 9.0f, 2.0f / 9.0f, 0.0f,
            0.0f,
            2.0f / 9.0f, 0.0f, 2.0f / 9.0f, 2.0f / 9.0f, 0.0f, 4.0f / 9.0f, 2.0f / 9.0f, 0.0f, 6.0f / 9.0f, 2.0f / 9.0f,
            0.0f,
            8.0f / 9.0f, 2.0f / 9.0f, 0.0f, -8.0f / 9.0f, 4.0f / 9.0f, 0.0f, -6.0f / 9.0f, 4.0f / 9.0f, 0.0f,
            -4.0f / 9.0f,
            4.0f / 9.0f, 0.0f, -2.0f / 9.0f, 4.0f / 9.0f, 0.0f, 0.0f, 4.0f / 9.0f, 0.0f, 2.0f / 9.0f, 4.0f / 9.0f, 0.0f,
            4.0f / 9.0f, 4.0f / 9.0f, 0.0f, 6.0f / 9.0f, 4.0f / 9.0f, 0.0f, 8.0f / 9.0f, 4.0f / 9.0f, 0.0f,
            -8.0f / 9.0f,
            6.0f / 9.0f, 0.0f, -6.0f / 9.0f, 6.0f / 9.0f, 0.0f, -4.0f / 9.0f, 6.0f / 9.0f, 0.0f, -2.0f / 9.0f,
            6.0f / 9.0f, 0.0f,
            0.0f, 6.0f / 9.0f, 0.0f, 2.0f / 9.0f, 6.0f / 9.0f, 0.0f, 4.0f / 9.0f, 6.0f / 9.0f, 0.0f, 6.0f / 9.0f,
            6.0f / 9.0f,
            0.0f, 8.0f / 9.0f, 6.0f / 9.0f, 0.0f, -8.0f / 9.0f, 8.0f / 9.0f, 0.0f, -6.0f / 9.0f, 8.0f / 9.0f, 0.0f,
            -4.0f / 9.0f,
            8.0f / 9.0f, 0.0f, -2.0f / 9.0f, 8.0f / 9.0f, 0.0f, 0.0f, 8.0f / 9.0f, 0.0f, 2.0f / 9.0f, 8.0f / 9.0f, 0.0f,
            4.0f / 9.0f, 8.0f / 9.0f, 0.0f, 6.0f / 9.0f, 8.0f / 9.0f, 0.0f, 8.0f / 9.0f, 8.0f / 9.0f, 0.0f,
            -8.0f / 9.0f,
            -8.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f,
            -2.0f / 9.0f,
            -8.0f / 9.0f, 2.0f / 9.0f, 0.0f, -8.0f / 9.0f,
            2.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f,
            -8.0f / 9.0f,
            2.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f,
            -6.0f / 9.0f,
            2.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 0.0f,
            -6.0f / 9.0f,
            2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f,
            -6.0f / 9.0f,
            2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f,
            -4.0f / 9.0f,
            2.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 0.0f,
            -4.0f / 9.0f,
            2.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f,
            -4.0f / 9.0f,
            2.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f,
            -2.0f / 9.0f,
            2.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 0.0f,
            -2.0f / 9.0f,
            2.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f,
            -2.0f / 9.0f,
            2.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 0.0f, 2.0f / 9.0f, -6.0f / 9.0f, 0.0f,
            2.0f / 9.0f,
            -4.0f / 9.0f, 0.0f, 2.0f / 9.0f, -2.0f / 9.0f, 0.0f, 2.0f / 9.0f, 0.0f, 0.0f, 2.0f / 9.0f, 2.0f / 9.0f,
            0.0f,
            2.0f / 9.0f, 4.0f / 9.0f, 0.0f, 2.0f / 9.0f, 6.0f / 9.0f, 0.0f, 2.0f / 9.0f, 8.0f / 9.0f, 0.0f, 2.0f / 9.0f,
            -8.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f,
            2.0f / 9.0f,
            -2.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 0.0f, 2.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f,
            2.0f / 9.0f, 4.0f / 9.0f,
            2.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f,
            -8.0f / 9.0f,
            4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f,
            4.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 0.0f, 4.0f / 9.0f, 2.0f / 9.0f,
            2.0f / 9.0f, 4.0f / 9.0f,
            2.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f,
            4.0f / 9.0f,
            2.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f,
            6.0f / 9.0f,
            2.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 0.0f, 6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f,
            6.0f / 9.0f, 2.0f / 9.0f,
            4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f,
            2.0f / 9.0f,
            -8.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f,
            2.0f / 9.0f,
            -2.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 0.0f, 8.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f,
            2.0f / 9.0f, 4.0f / 9.0f,
            8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f,
            -8.0f / 9.0f,
            -8.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f,
            -2.0f / 9.0f,
            -8.0f / 9.0f, 4.0f / 9.0f, 0.0f, -8.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f,
            4.0f / 9.0f,
            -8.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f,
            -8.0f / 9.0f,
            -6.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f,
            -2.0f / 9.0f,
            -6.0f / 9.0f, 4.0f / 9.0f, 0.0f, -6.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f,
            4.0f / 9.0f,
            -6.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f,
            -8.0f / 9.0f,
            -4.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f,
            -2.0f / 9.0f,
            -4.0f / 9.0f, 4.0f / 9.0f, 0.0f, -4.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f,
            4.0f / 9.0f,
            -4.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f,
            4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f,
            -2.0f / 9.0f,
            4.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, 0.0f,
            -2.0f / 9.0f,
            4.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f,
            -2.0f / 9.0f,
            4.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, 0.0f, 4.0f / 9.0f, -6.0f / 9.0f, 0.0f,
            4.0f / 9.0f,
            -4.0f / 9.0f, 0.0f, 4.0f / 9.0f, -2.0f / 9.0f, 0.0f, 4.0f / 9.0f, 0.0f, 0.0f, 4.0f / 9.0f, 2.0f / 9.0f,
            0.0f,
            4.0f / 9.0f, 4.0f / 9.0f, 0.0f, 4.0f / 9.0f, 6.0f / 9.0f, 0.0f, 4.0f / 9.0f, 8.0f / 9.0f, 0.0f, 4.0f / 9.0f,
            -8.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 2.0f / 9.0f,
            4.0f / 9.0f,
            -2.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 0.0f, 2.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f,
            4.0f / 9.0f, 4.0f / 9.0f,
            2.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f,
            -8.0f / 9.0f,
            4.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f,
            -2.0f / 9.0f,
            4.0f / 9.0f, 4.0f / 9.0f, 0.0f, 4.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f,
            4.0f / 9.0f, 4.0f / 9.0f,
            4.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f,
            6.0f / 9.0f,
            4.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f,
            6.0f / 9.0f,
            4.0f / 9.0f, 0.0f, 6.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f,
            6.0f / 9.0f, 4.0f / 9.0f,
            6.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f,
            4.0f / 9.0f,
            -6.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f,
            4.0f / 9.0f,
            0.0f, 8.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f,
            4.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f,
            -8.0f / 9.0f,
            6.0f / 9.0f, -6.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f,
            -8.0f / 9.0f,
            6.0f / 9.0f, 0.0f, -8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f,
            -8.0f / 9.0f,
            6.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f,
            -6.0f / 9.0f,
            6.0f / 9.0f, -6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f,
            -6.0f / 9.0f,
            6.0f / 9.0f, 0.0f, -6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f,
            -6.0f / 9.0f,
            6.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f,
            -4.0f / 9.0f,
            6.0f / 9.0f, -6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f,
            -4.0f / 9.0f,
            6.0f / 9.0f, 0.0f, -4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f,
            -4.0f / 9.0f,
            6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f,
            -2.0f / 9.0f,
            6.0f / 9.0f, -6.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f,
            -2.0f / 9.0f,
            6.0f / 9.0f, 0.0f, -2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f,
            -2.0f / 9.0f,
            6.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f,
            0.0f,
            6.0f / 9.0f, -6.0f / 9.0f, 0.0f, 6.0f / 9.0f, -4.0f / 9.0f, 0.0f, 6.0f / 9.0f, -2.0f / 9.0f, 0.0f,
            6.0f / 9.0f, 0.0f,
            0.0f, 6.0f / 9.0f, 2.0f / 9.0f, 0.0f, 6.0f / 9.0f, 4.0f / 9.0f, 0.0f, 6.0f / 9.0f, 6.0f / 9.0f, 0.0f,
            6.0f / 9.0f,
            8.0f / 9.0f, 0.0f, 6.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f,
            6.0f / 9.0f,
            -4.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f,
            0.0f, 2.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f,
            6.0f / 9.0f, 6.0f / 9.0f,
            2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f,
            -6.0f / 9.0f,
            4.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f,
            0.0f,
            4.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f,
            6.0f / 9.0f,
            4.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f,
            -6.0f / 9.0f,
            6.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f,
            0.0f,
            6.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f,
            6.0f / 9.0f,
            6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f,
            -6.0f / 9.0f,
            8.0f / 9.0f, 6.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f,
            0.0f,
            8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f,
            6.0f / 9.0f,
            8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, -8.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f,
            -6.0f / 9.0f,
            -8.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f,
            0.0f,
            -8.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f,
            6.0f / 9.0f,
            -8.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f,
            -6.0f / 9.0f,
            -6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f,
            0.0f,
            -6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f,
            6.0f / 9.0f,
            -6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f,
            -6.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f,
            -4.0f / 9.0f, 8.0f / 9.0f,
            0.0f, -4.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -4.0f / 9.0f,
            8.0f / 9.0f,
            6.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, -2.0f / 9.0f,
            8.0f / 9.0f,
            -6.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f,
            -2.0f / 9.0f, 8.0f / 9.0f,
            0.0f, -2.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f, -2.0f / 9.0f,
            8.0f / 9.0f,
            6.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 0.0f,
            8.0f / 9.0f,
            -6.0f / 9.0f, 0.0f, 8.0f / 9.0f, -4.0f / 9.0f, 0.0f, 8.0f / 9.0f, -2.0f / 9.0f, 0.0f, 8.0f / 9.0f, 0.0f,
            0.0f,
            8.0f / 9.0f, 2.0f / 9.0f, 0.0f, 8.0f / 9.0f, 4.0f / 9.0f, 0.0f, 8.0f / 9.0f, 6.0f / 9.0f, 0.0f, 8.0f / 9.0f,
            8.0f / 9.0f,
            0.0f, 8.0f / 9.0f, -8.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f,
            -4.0f / 9.0f,
            2.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 0.0f, 2.0f / 9.0f, 8.0f / 9.0f,
            2.0f / 9.0f, 2.0f / 9.0f,
            8.0f / 9.0f, 4.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 2.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f,
            2.0f / 9.0f,
            8.0f / 9.0f, -8.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f,
            4.0f / 9.0f,
            8.0f / 9.0f, -2.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 0.0f, 4.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f,
            4.0f / 9.0f, 8.0f / 9.0f,
            4.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 4.0f / 9.0f,
            8.0f / 9.0f,
            -8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, -4.0f / 9.0f, 6.0f / 9.0f,
            8.0f / 9.0f,
            -2.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 0.0f, 6.0f / 9.0f, 8.0f / 9.0f, 2.0f / 9.0f, 6.0f / 9.0f,
            8.0f / 9.0f, 4.0f / 9.0f,
            6.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f,
            6.0f / 9.0f, 8.0f / 9.0f, -8.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, -6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f,
            -4.0f / 9.0f,
            8.0f / 9.0f, 8.0f / 9.0f, -2.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 0.0f, 8.0f / 9.0f, 8.0f / 9.0f,
            2.0f / 9.0f, 8.0f / 9.0f,
            8.0f / 9.0f, 4.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 6.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f, 8.0f / 9.0f,
            8.0f / 9.0f,
            8.0f / 9.0f
        };

        // data taken from ISO/IEC DIS 11172, Annexes 3-B.2[abcd] and 3-B.4:

        // subbands 0-2 in tables 3-B.2a and 2b: (index is allocation)
        public static readonly int[] table_ab1_codelength = { 0, 5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };

        public static readonly float[][] table_ab1_groupingtables =
        {
            null, grouping_5bits, null, null, null, null,
            null, null, null, null, null, null, null, null, null, null
        };

        public static readonly float[] table_ab1_factor =
        {
            0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 8.0f, 1.0f / 16.0f, 1.0f / 32.0f, 1.0f / 64.0f, 1.0f / 128.0f,
            1.0f / 256.0f,
            1.0f / 512.0f, 1.0f / 1024.0f, 1.0f / 2048.0f, 1.0f / 4096.0f, 1.0f / 8192.0f, 1.0f / 16384.0f,
            1.0f / 32768.0f
        };

        public static readonly float[] table_ab1_c =
        {
            0.0f, 1.33333333333f, 1.14285714286f, 1.06666666666f, 1.03225806452f, 1.01587301587f, 1.00787401575f,
            1.00392156863f, 1.00195694716f, 1.00097751711f, 1.00048851979f, 1.00024420024f, 1.00012208522f,
            1.00006103888f, 1.00003051851f, 1.00001525902f
        };

        public static readonly float[] table_ab1_d =
        {
            0.0f, 0.50000000000f, 0.25000000000f, 0.12500000000f, 0.06250000000f, 0.03125000000f, 0.01562500000f,
            0.00781250000f, 0.00390625000f, 0.00195312500f, 0.00097656250f, 0.00048828125f, 0.00024414063f,
            0.00012207031f, 0.00006103516f, 0.00003051758f
        };

        // subbands 3-... tables 3-B.2a and 2b:
        public static readonly float[][] table_ab234_groupingtables =
        {
            null, grouping_5bits, grouping_7bits, null,
            grouping_10bits, null, null, null, null, null, null, null, null, null, null, null
        };

        // subbands 3-10 in tables 3-B.2a and 2b:
        public static readonly int[] table_ab2_codelength = { 0, 5, 7, 3, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 };

        public static readonly float[] table_ab2_factor =
        {
            0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 4.0f, 1.0f / 8.0f, 1.0f / 8.0f, 1.0f / 16.0f, 1.0f / 32.0f,
            1.0f / 64.0f,
            1.0f / 128.0f, 1.0f / 256.0f, 1.0f / 512.0f, 1.0f / 1024.0f, 1.0f / 2048.0f, 1.0f / 4096.0f, 1.0f / 32768.0f
        };

        public static readonly float[] table_ab2_c =
        {
            0.0f, 1.33333333333f, 1.60000000000f, 1.14285714286f, 1.77777777777f, 1.06666666666f, 1.03225806452f,
            1.01587301587f, 1.00787401575f, 1.00392156863f, 1.00195694716f, 1.00097751711f, 1.00048851979f,
            1.00024420024f, 1.00012208522f, 1.00001525902f
        };

        public static readonly float[] table_ab2_d =
        {
            0.0f, 0.50000000000f, 0.50000000000f, 0.25000000000f, 0.50000000000f, 0.12500000000f, 0.06250000000f,
            0.03125000000f, 0.01562500000f, 0.00781250000f, 0.00390625000f, 0.00195312500f, 0.00097656250f,
            0.00048828125f, 0.00024414063f, 0.00003051758f
        };

        // subbands 11-22 in tables 3-B.2a and 2b:
        public static readonly int[] table_ab3_codelength = { 0, 5, 7, 3, 10, 4, 5, 16 };

        public static readonly float[] table_ab3_factor =
        {
            0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 4.0f, 1.0f / 8.0f,
            1.0f / 8.0f, 1.0f / 16.0f, 1.0f / 32768.0f
        };

        public static readonly float[] table_ab3_c =
        {
            0.0f, 1.33333333333f, 1.60000000000f, 1.14285714286f, 1.77777777777f, 1.06666666666f, 1.03225806452f,
            1.00001525902f
        };

        public static readonly float[] table_ab3_d =
        {
            0.0f, 0.50000000000f, 0.50000000000f, 0.25000000000f, 0.50000000000f, 0.12500000000f, 0.06250000000f,
            0.00003051758f
        };

        // subbands 23-... in tables 3-B.2a and 2b:
        public static readonly int[] table_ab4_codelength = { 0, 5, 7, 16 };
        public static readonly float[] table_ab4_factor = { 0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 32768.0f };
        public static readonly float[] table_ab4_c = { 0.0f, 1.33333333333f, 1.60000000000f, 1.00001525902f };
        public static readonly float[] table_ab4_d = { 0.0f, 0.50000000000f, 0.50000000000f, 0.00003051758f };
        // subbands in tables 3-B.2c and 2d:
        public static readonly int[] table_cd_codelength = { 0, 5, 7, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

        public static readonly float[][] table_cd_groupingtables =
        {
            null, grouping_5bits, grouping_7bits,
            grouping_10bits, null, null, null, null, null, null, null, null, null, null, null, null
        };

        public static readonly float[] table_cd_factor =
        {
            0.0f, 1.0f / 2.0f, 1.0f / 4.0f, 1.0f / 8.0f, 1.0f / 8.0f, 1.0f / 16.0f, 1.0f / 32.0f, 1.0f / 64.0f,
            1.0f / 128.0f,
            1.0f / 256.0f, 1.0f / 512.0f, 1.0f / 1024.0f, 1.0f / 2048.0f, 1.0f / 4096.0f, 1.0f / 8192.0f,
            1.0f / 16384.0f
        };

        public static readonly float[] table_cd_c =
        {
            0.0f, 1.33333333333f, 1.60000000000f, 1.77777777777f, 1.06666666666f, 1.03225806452f, 1.01587301587f,
            1.00787401575f, 1.00392156863f, 1.00195694716f, 1.00097751711f, 1.00048851979f, 1.00024420024f,
            1.00012208522f, 1.00006103888f, 1.00003051851f
        };

        public static readonly float[] table_cd_d =
        {
            0.0f, 0.50000000000f, 0.50000000000f, 0.50000000000f, 0.12500000000f, 0.06250000000f, 0.03125000000f,
            0.01562500000f, 0.00781250000f, 0.00390625000f, 0.00195312500f, 0.00097656250f, 0.00048828125f,
            0.00024414063f, 0.00012207031f, 0.00006103516f
        };

        /// <summary>
        ///     Constructor
        /// </summary>
        public SubbandLayer2(int subbandnumber)
        {
            this.subbandnumber = subbandnumber;
            groupnumber = samplenumber = 0;
        }

        protected internal int allocation;
        protected internal float[] c = { 0 };
        protected internal int[] codelength = { 0 };
        protected internal float[] d = { 0 };
        //protected float[][] groupingtable = {{0},{0}} ;
        protected internal float[] factor = { 0.0f };
        protected internal float[][] groupingtable;
        protected internal int groupnumber;
        protected internal int samplenumber;
        protected internal float[] samples;
        protected internal float scalefactor1, scalefactor2, scalefactor3;
        protected internal int scfsi;
        protected internal int subbandnumber;

        private void InitBlock()
        {
            samples = new float[3];
            groupingtable = new float[2][];
        }

        /// <summary>
        ///     *
        /// </summary>
        protected internal virtual int get_allocationlength(Header header)
        {
            if (header.version() == Header.MPEG1)
            {
                int channel_bitrate = header.bitrate_index();

                // calculate bitrate per channel:
                if (header.mode() != Header.SINGLE_CHANNEL)
                {
                    if (channel_bitrate == 4)
                    {
                        channel_bitrate = 1;
                    }
                    else
                    {
                        channel_bitrate -= 4;
                    }
                }

                if (channel_bitrate == 1 || channel_bitrate == 2)
                    // table 3-B.2c or 3-B.2d
                {
                    if (subbandnumber <= 1)
                    {
                        return 4;
                    }

                    return 3;
                }

                // tables 3-B.2a or 3-B.2b
                if (subbandnumber <= 10)
                {
                    return 4;
                }

                if (subbandnumber <= 22)
                {
                    return 3;
                }

                return 2;
            }
            // MPEG-2 LSF -- Jeff

            // table B.1 of ISO/IEC 13818-3
            if (subbandnumber <= 3)
            {
                return 4;
            }

            if (subbandnumber <= 10)
            {
                return 3;
            }

            return 2;
        }

        /// <summary>
        ///     *
        /// </summary>
        protected internal virtual void prepare_sample_reading
        (
            Header header,
            int allocation,
            int channel,
            float[] factor,
            int[] codelength,
            float[] c,
            float[] d
        )
        {
            int channel_bitrate = header.bitrate_index();

            // calculate bitrate per channel:
            if (header.mode() != Header.SINGLE_CHANNEL)
            {
                if (channel_bitrate == 4)
                {
                    channel_bitrate = 1;
                }
                else
                {
                    channel_bitrate -= 4;
                }
            }

            if (channel_bitrate == 1 || channel_bitrate == 2)
            {
                // table 3-B.2c or 3-B.2d
                groupingtable[channel] = table_cd_groupingtables[allocation];
                factor[0] = table_cd_factor[allocation];
                codelength[0] = table_cd_codelength[allocation];
                c[0] = table_cd_c[allocation];
                d[0] = table_cd_d[allocation];
            }
            else
            {
                // tables 3-B.2a or 3-B.2b
                if (subbandnumber <= 2)
                {
                    groupingtable[channel] = table_ab1_groupingtables[allocation];
                    factor[0] = table_ab1_factor[allocation];
                    codelength[0] = table_ab1_codelength[allocation];
                    c[0] = table_ab1_c[allocation];
                    d[0] = table_ab1_d[allocation];
                }
                else
                {
                    groupingtable[channel] = table_ab234_groupingtables[allocation];

                    if (subbandnumber <= 10)
                    {
                        factor[0] = table_ab2_factor[allocation];
                        codelength[0] = table_ab2_codelength[allocation];
                        c[0] = table_ab2_c[allocation];
                        d[0] = table_ab2_d[allocation];
                    }
                    else if (subbandnumber <= 22)
                    {
                        factor[0] = table_ab3_factor[allocation];
                        codelength[0] = table_ab3_codelength[allocation];
                        c[0] = table_ab3_c[allocation];
                        d[0] = table_ab3_d[allocation];
                    }
                    else
                    {
                        factor[0] = table_ab4_factor[allocation];
                        codelength[0] = table_ab4_codelength[allocation];
                        c[0] = table_ab4_c[allocation];
                        d[0] = table_ab4_d[allocation];
                    }
                }
            }
        }

        /// <summary>
        ///     *
        /// </summary>
        public override void read_allocation(Bitstream stream, Header header, Crc16 crc)
        {
            int length = get_allocationlength(header);
            allocation = stream.GetBitsFromBuffer(length);

            if (crc != null)
            {
                crc.add_bits(allocation, length);
            }
        }

        /// <summary>
        ///     *
        /// </summary>
        public virtual void read_scalefactor_selection(Bitstream stream, Crc16 crc)
        {
            if (allocation != 0)
            {
                scfsi = stream.GetBitsFromBuffer(2);

                if (crc != null)
                {
                    crc.add_bits(scfsi, 2);
                }
            }
        }

        /// <summary>
        ///     *
        /// </summary>
        public override void read_scalefactor(Bitstream stream, Header header)
        {
            if (allocation != 0)
            {
                switch (scfsi)
                {
                    case 0:
                        scalefactor1 = ScaleFactors[stream.GetBitsFromBuffer(6)];
                        scalefactor2 = ScaleFactors[stream.GetBitsFromBuffer(6)];
                        scalefactor3 = ScaleFactors[stream.GetBitsFromBuffer(6)];

                        break;

                    case 1:
                        scalefactor1 = scalefactor2 = ScaleFactors[stream.GetBitsFromBuffer(6)];
                        scalefactor3 = ScaleFactors[stream.GetBitsFromBuffer(6)];

                        break;

                    case 2:
                        scalefactor1 = scalefactor2 = scalefactor3 = ScaleFactors[stream.GetBitsFromBuffer(6)];

                        break;

                    case 3:
                        scalefactor1 = ScaleFactors[stream.GetBitsFromBuffer(6)];
                        scalefactor2 = scalefactor3 = ScaleFactors[stream.GetBitsFromBuffer(6)];

                        break;
                }

                prepare_sample_reading
                (
                    header,
                    allocation,
                    0,
                    factor,
                    codelength,
                    c,
                    d
                );
            }
        }

        /// <summary>
        ///     *
        /// </summary>
        public override bool read_sampledata(Bitstream stream)
        {
            if (allocation != 0)
            {
                if (groupingtable[0] != null)
                {
                    int samplecode = stream.GetBitsFromBuffer(codelength[0]);
                    // create requantized samples:
                    samplecode += samplecode << 1;
                    float[] target = samples;
                    float[] source = groupingtable[0];
                    /*
                    int tmp = 0;
                    int temp = 0;
                    target[tmp++] = source[samplecode + temp];
                    temp++;
                    target[tmp++] = source[samplecode + temp];
                    temp++;
                    target[tmp] = source[samplecode + temp];
                    */
                    //Bugfix:
                    int tmp = 0;
                    int temp = samplecode;

                    if (temp > source.Length - 3)
                    {
                        temp = source.Length - 3;
                    }

                    target[tmp] = source[temp];
                    temp++;
                    tmp++;
                    target[tmp] = source[temp];
                    temp++;
                    tmp++;
                    target[tmp] = source[temp];

                    // memcpy (samples, groupingtable + samplecode, 3 * sizeof (real));
                }
                else
                {
                    samples[0] = (float) (stream.GetBitsFromBuffer(codelength[0]) * factor[0] - 1.0);
                    samples[1] = (float) (stream.GetBitsFromBuffer(codelength[0]) * factor[0] - 1.0);
                    samples[2] = (float) (stream.GetBitsFromBuffer(codelength[0]) * factor[0] - 1.0);
                }
            }

            samplenumber = 0;

            if (++groupnumber == 12)
            {
                return true;
            }

            return false;
        }

        /// <summary>
        ///     *
        /// </summary>
        public override bool put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2)
        {
            if (allocation != 0 && channels != OutputChannels.RIGHT_CHANNEL)
            {
                float sample = samples[samplenumber];

                if (groupingtable[0] == null)
                {
                    sample = (sample + d[0]) * c[0];
                }

                if (groupnumber <= 4)
                {
                    sample *= scalefactor1;
                }
                else if (groupnumber <= 8)
                {
                    sample *= scalefactor2;
                }
                else
                {
                    sample *= scalefactor3;
                }

                filter1.input_sample(sample, subbandnumber);
            }

            if (++samplenumber == 3)
            {
                return true;
            }

            return false;
        }
    }
}